/** 
 * url: 连接地址
 * messageCallback: 成功回调函数如：wsMessage(res) { consolr.log('返回数据', res) })
 * isHeartCheck： 是否使用心跳检测,默认为false
 * ping: 心跳检测发送信息, 默认为ping
 * pong: 心跳检测接受信息，默认为pong
 */
import {
    ElMessage
} from 'element-plus';
class WebSocketClass {
    constructor(url, messageCallback, isHeartCheck = false, ping = 'ping', pong = 'pong', ) {
        this.instance = null;
        this.url = url;
        this.messageCallback = messageCallback;
        this.isHeartCheck = isHeartCheck;
        this.ping = ping;
        this.pong = pong;
        this.connect();
    }
    static getInstance() {
        if (!this.instance) {
            this.instance = new WebSocketClass();
        }
        return this.instance;
    }

    connect() {
        this.ws = new WebSocket(this.url);
        this.ws.onopen = e => {
            this.status = 'open';
            ElMessage({
                type: 'success',
                showClose: true,
                message: 'ws连接成功！'
            });
            // console.log(`连接成功`, e);
            this.isHeartCheck && this.heartCheck();
            this.getMessage();
        };
    }

    heartCheck() {
        // 心跳机制的时间可以自己与后端约定
        this.pingPong = this.ping; // ws的心跳机制状态值
        this.pingInterval = setInterval(() => {
            if (this.ws.readyState === 1) {
                // 检查ws为链接状态 才可发送
                this.ws.send(ping); // 客户端发送ping
            }
        }, 10000);
        this.pongInterval = setInterval(() => {
            if (this.pingPong === this.ping) {
                this.closeHandle('pingPong没有改变为' + this.ping); // 没有返回pong 重启webSocket
            }
            // 重置为ping 若下一次 ping 发送失败 或者pong返回失败(pingPong不会改成pong)，将重启
            console.log('返回' + this.pong);
            this.pingPong = this.ping;
        }, 20000);
    }

    closeHandle(e = 'err') {
        // 因为webSocket并不稳定，规定只能手动关闭(调closeMyself方法)，否则就重连
        if (this.status !== 'close') {
            console.log(`断开，重连websocket`, e);
            if (this.pingInterval !== undefined && this.pongInterval !== undefined) {
                // 清除定时器
                clearInterval(this.pingInterval);
                clearInterval(this.pongInterval);
            }
            this.connect(); // 重连
        } else {
            console.log(`websocket手动关闭,或者正在连接`);
        }
    }

    getMessage() {
        this.ws.onmessage = e => {
            if (e.data === this.pong) {
                this.pingPong = this.pong; // 服务器端返回pong,修改pingPong的状态
            } else {
                //   message.info(e.data);
                this.messageCallback(e.data)
            }
        };
    }

    send(data) {
        let that = this;
        setTimeout(() => {
            if (that.ws.readyState === that.ws.OPEN) {
                that.ws.send(JSON.stringify(data));
            }
            if (that.ws.readyState === that.ws.CLOSED) {
                ElMessage.closeAll();
                ElMessage({
                    type: 'warning',
                    showClose: true,
                    message: 'ws连接异常，请稍候重试！'
                });
            }
        }, 500);
    }

    close() {
        clearInterval(this.pingInterval);
        clearInterval(this.pongInterval);
        this.status = 'close';
        this.ws.send('close');
        this.ws.close();
        ElMessage.warning({
            message: '已断开连接',
            type: 'warning'
        });
        console.log('close');
    }
}

export default WebSocketClass;